using System;
using Wikey.Extensibility.Enums;
using Wikey.Extensibility.Interfaces;

namespace Wikey.Transformation
{
    public class Token : IToken
    {

        public readonly static Token LeftBracket = new Token(TokenType.LeftBracket);
        public readonly static Token Equal = new Token(TokenType.Equal);
        public readonly static Token SemiColumn = new Token(TokenType.SemiColumn);
        public readonly static Token Seperator = new Token(TokenType.Seperator);
        public readonly static Token RightBracket = new Token(TokenType.RightBracket);
        public readonly static Token Space = new Token(TokenType.Space);
        public string Value { get; set; }
        public TokenType Type { get; set; }
        public Token() {

        }

        public Token(string value, TokenType type)
        {
            Value = value;
            Type = type;
        }

        public Token(TokenType type) : this(String.Empty, type) { }

        public override bool Equals(object obj) {
            if (false == (obj is Token)) return false;

            Token second = obj as Token;

            //if current object is null , we can't be here , right ?
            if (second == null) return false;

            return second.Type == this.Type && second.Value.Equals(this.Value);
        }

        public static bool operator ==(Token first, Token second) {
            if (ReferenceEquals(first, second))
                return true;
            // If one is null, but not both, return false.
            if (((object)first == null) || ((object)second == null)) {
                return false;
            }

            return first.Type == second.Type && first.Value == second.Value;
        }

        public static bool operator !=(Token first, Token second) {
            return !(first == second);
        }

        public bool Equals(IToken other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return Equals(other.Value, Value) && Equals(other.Type, Type);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return ((Value != null ? Value.GetHashCode() : 0)*397) ^ Type.GetHashCode();
            }
        }

        public override string ToString() {
            return String.Format("{0}|{1}|", this.Type, Value);
        }
    }

}